package com.example.bbs.ui.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.bbs.R;

// 版权声明：本文为CSDN博主「Android小安」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
// 原文链接：https://blog.csdn.net/Coo123_/article/details/86702666
@SuppressWarnings("unused")
public class RoundRectLayout extends FrameLayout {

    float leftTopRound;
    float rightTopRound;
    float leftBottomRound;
    float rightBottomRound;
    boolean mClipping;
    RectF mRectF;
    Path mPath = new Path();
    Paint mPaint;

    public RoundRectLayout(@NonNull Context context) {
        super(context);
    }

    public RoundRectLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public RoundRectLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    public void init(Context context, AttributeSet attrs) {
        TypedArray obtainedAttrs = context.obtainStyledAttributes(attrs, R.styleable.RoundRectLayout);
        leftTopRound = obtainedAttrs.getDimension(R.styleable.RoundRectLayout_leftTopRound, 0);
        rightTopRound = obtainedAttrs.getDimension(R.styleable.RoundRectLayout_rightTopRound, 0);
        leftBottomRound = obtainedAttrs.getDimension(R.styleable.RoundRectLayout_leftBottomRound, 0);
        rightBottomRound = obtainedAttrs.getDimension(R.styleable.RoundRectLayout_rightBottomRound, 0);
        mClipping = obtainedAttrs.getBoolean(R.styleable.RoundRectLayout_clipping, true);
        float round;
        if ((round = obtainedAttrs.getDimension(R.styleable.RoundRectLayout_round, 0)) != 0)
            leftTopRound = rightTopRound = leftBottomRound = rightBottomRound = round;
        obtainedAttrs.recycle();

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mRectF = new RectF(0, 0, getWidth(), getHeight());
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    }

    public void setRound(float leftTop, float rightTop, float leftBottom, float rightBottom) {
        leftTopRound = leftTop;
        rightTopRound = rightTop;
        leftBottomRound = leftBottom;
        rightBottomRound = rightBottom;
    }

    public void setRound(float round) {
        leftTopRound = rightTopRound = leftBottomRound = rightBottomRound = round;
    }

    public void enableClipping(boolean clipping) {
        mClipping = clipping;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        super.onSizeChanged(w, h, oldW, oldH);
        if (mRectF != null)
            mRectF.set(0, 0, w, h);
        else
            mRectF = new RectF(0, 0, w, h);
    }

    @SuppressLint({"MissingSuperCall", "ObsoleteSdkInt"})
    @Override
    public void draw(Canvas canvas) {
        if (Build.VERSION.SDK_INT >= 28) {
            draw28(canvas);
        } else {
            draw27(canvas);
        }
    }

    @SuppressLint("ObsoleteSdkInt")
    @Override
    protected void dispatchDraw(Canvas canvas) {
        if (Build.VERSION.SDK_INT >= 28) {
            dispatchDraw28(canvas);
        } else {
            dispatchDraw27(canvas);
        }
    }

    @SuppressWarnings("deprecation")
    private void draw27(Canvas canvas) {
        if (mClipping) {
            canvas.saveLayer(mRectF, null, Canvas.ALL_SAVE_FLAG);
            super.draw(canvas);
            canvas.drawPath(genPath(), mPaint);
            canvas.restore();
        } else {
            super.draw(canvas);
        }
    }

    private void draw28(Canvas canvas) {
        if (mClipping) {
            canvas.save();
            canvas.clipPath(genPath());
            super.draw(canvas);
            canvas.restore();
        } else {
            super.draw(canvas);
        }
    }

    @SuppressWarnings("deprecation")
    private void dispatchDraw27(Canvas canvas) {
        canvas.saveLayer(mRectF, null, Canvas.ALL_SAVE_FLAG);
        super.dispatchDraw(canvas);
        canvas.drawPath(genPath(), mPaint);
        canvas.restore();
    }

    private void dispatchDraw28(Canvas canvas) {
        canvas.save();
        canvas.clipPath(genPath());
        super.dispatchDraw(canvas);
        canvas.restore();
    }

    private Path genPath() {
        mPath.reset();
        mPath.addRoundRect(mRectF,
                new float[]{leftTopRound, leftTopRound, rightTopRound, rightTopRound, rightBottomRound, rightBottomRound, leftBottomRound, leftBottomRound},
                Path.Direction.CW);
        return mPath;
    }

/*  @Override
    public void dispatchDraw(Canvas canvas) {
        canvas.clipPath(mPath);
        super.dispatchDraw(canvas);
    }*/

    @Override
    public boolean shouldDelayChildPressedState() {
        return false;
    }
}
